<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Color 4: Resolving HSL color values</title>
<link rel="author" title="Chris Nardi" href="mailto:csnardi1@gmail.com">
<link rel="help" href="https://drafts.csswg.org/css-color-4/#resolving-color-values">
<meta name="assert" content="Tests if HSL color values are resolved properly">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<div id="parent" style="color: rgb(45, 23, 27)">
    <div id="inner"></div>
</div>

<script>
    function color_test(color, expected, reason) {
        test(function() {
            var element = document.getElementById('inner');
            // Random value not in our test data.
            fail_value = "rgb(12, 34, 223)"
            element.style.color = "black";
            element.style.cssText = "color: " + fail_value + "; color: " + color;

            if (expected === null)
                assert_equals(getComputedStyle(element).color, fail_value);
            else
                assert_equals(getComputedStyle(element).color, expected);
        }, `${reason}: ${color}`);
    }

    function expected_value(rgb_channels) {
        if (rgb_channels === null)
            return null;
        else if (rgb_channels.length === 3 || rgb_channels[3] == 1 || rgb_channels[3] === undefined)
            return "rgb(" + rgb_channels.slice(0, 3).join(", ") + ")";
        else
            return "rgba(" + rgb_channels.join(", ") + ")";
    }

    // Taken mostly from https://drafts.csswg.org/css-color/#hsl-to-rgb
    function hslToRgb(hue, sat, light) {
      if (light <= .5) {
        var t2 = light * (sat + 1);
      } else {
        var t2 = light + sat - (light * sat);
      }
      var t1 = light * 2 - t2;
      var r = Math.min(Math.max(Math.round(hueToRgb(t1, t2, hue + 2) * 255), 0), 255);
      var g = Math.min(Math.max(Math.round(hueToRgb(t1, t2, hue) * 255), 0), 255);
      var b = Math.min(Math.max(Math.round(hueToRgb(t1, t2, hue - 2) * 255), 0), 255);
      return [r,g,b];
    }

    function hueToRgb(t1, t2, hue) {
      if (hue < 0) hue += 6;
      if (hue >= 6) hue -= 6;

      if (hue < 1) return (t2 - t1) * hue + t1;
      else if (hue < 3) return t2;
      else if (hue < 4) return (t2 - t1) * (4 - hue) + t1;
      else return t1;
    }

    // Test HSL parsing
    for (var hue of [0, 30, 60, 90, 120, 180, 210, 240, 270, 300, 330, 360]) {
        for (var sat of [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]) {
            for (var light of [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]) {
                rgb_channels = hslToRgb(hue / 60, sat, light);
                for (var alpha of [undefined, 0, 0.2, 1]) {
                    hsl_color = "hsl(" + hue + ", " + sat * 100 + "%, " + light * 100 + "%)";
                    rgb_channels[3] = alpha;
                    if (alpha !== undefined) {
                        hsl_color = "hsla(" + hue + ", " + sat * 100 + "%, " + light * 100 + "%, " + alpha + ")";
                    }
                    color_test(hsl_color, expected_value(rgb_channels), "HSL/HSLA value should parse and round correctly");
                }
            }
        }
    }
</script>
